/**
 * 
 */
package ro.utcn.oop.mandelbrot.rmi.client;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import ro.utcn.oop.mandelbrot.rmi.server.IMandelbrotService;

/**
 * @author coni
 * 
 */
public class MandelbrotServicePool {
//se creaza mai multe proxy pentru mandelbrot service
	private static MandelbrotServicePool instance;

	public static synchronized MandelbrotServicePool getInstance() {
		if (instance == null) {
			instance = new MandelbrotServicePool();
		}
		return instance;
	}
//listele pt proxy: o lista pentru free, una pt used
	private List<IMandelbrotService> mandelbrotServiceProxyFree;
	private List<IMandelbrotService> mandelbrotServiceProxyUsed;

	private MandelbrotServicePool() {
		mandelbrotServiceProxyFree = new ArrayList<IMandelbrotService>();
		mandelbrotServiceProxyUsed = new ArrayList<IMandelbrotService>();
		try {//instantiaza un xml in care e definit conectorul la rmi
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"ro/utcn/oop/mandelbrot/rmi/client/remoting-client-context1.xml");
			IMandelbrotService mandelbrotServiceProxy = (IMandelbrotService) ctx
					.getBean("mandelbrotService");//se obtine benul pt mandel service care se pune in lista de proxy free
			mandelbrotServiceProxyFree.add(mandelbrotServiceProxy);
		} catch (Exception e) {
			// e.printStackTrace();
		}
		try {
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"ro/utcn/oop/mandelbrot/rmi/client/remoting-client-context2.xml");
			IMandelbrotService mandelbrotServiceProxy = (IMandelbrotService) ctx
					.getBean("mandelbrotService");
			mandelbrotServiceProxyFree.add(mandelbrotServiceProxy);
		} catch (Exception e) {
			// e.printStackTrace();
		}
		try {
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"ro/utcn/oop/mandelbrot/rmi/client/remoting-client-context3.xml");
			IMandelbrotService mandelbrotServiceProxy = (IMandelbrotService) ctx
					.getBean("mandelbrotService");
			mandelbrotServiceProxyFree.add(mandelbrotServiceProxy);
		} catch (Exception e) {
			// e.printStackTrace();
		}
		try {
			ApplicationContext ctx = new ClassPathXmlApplicationContext(
					"ro/utcn/oop/mandelbrot/rmi/client/remoting-client-context4.xml");
			IMandelbrotService mandelbrotServiceProxy = (IMandelbrotService) ctx
					.getBean("mandelbrotService");
			mandelbrotServiceProxyFree.add(mandelbrotServiceProxy);
		} catch (Exception e) {
			// e.pSrintStackTrace();
		}
	}

	/**
	 * @return the mandelbrotServiceProxy
	 */
	public IMandelbrotService getFreeMandelbrotServiceProxy() {//cand porneste un tread se apeleaza metoda pt a obtine un proxy pe care sa il foloseasca  sa calculeze
		IMandelbrotService mandelbrotServiceProxy = null;
		while (mandelbrotServiceProxy == null) {
			mandelbrotServiceProxy = getFreeMandelbrotService();//incearca sa obtina un free proxy
			if (mandelbrotServiceProxy == null) {
				try {
					Thread.sleep(100);//doarme 100 ms si incearca din nou
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
		return mandelbrotServiceProxy;
	}


	private synchronized IMandelbrotService getFreeMandelbrotService() {//daca lista cu proxy free e mai mare ca 0
		IMandelbrotService mandelbrotServiceProxy = null;
		if (mandelbrotServiceProxyFree.size() > 0) {
			mandelbrotServiceProxy = mandelbrotServiceProxyFree.get(0);
			mandelbrotServiceProxyFree.remove(mandelbrotServiceProxy);//il scoate din remove
			mandelbrotServiceProxyUsed.add(mandelbrotServiceProxy);//il pune in free
		}
		return mandelbrotServiceProxy;
	}

	/**
	 * @return the mandelbrotServiceProxy
	 */
	public synchronized void releaseMandelbrotServiceProxy(//scoate din used si pune proxy in free
			IMandelbrotService mandelbrotServiceProxy) {
		mandelbrotServiceProxyUsed.remove(mandelbrotServiceProxy);
		mandelbrotServiceProxyFree.add(mandelbrotServiceProxy);
	}

}
